package com.example.mydemo;

import com.example.mydemo.config.ESTestRepository;
import com.example.mydemo.entity.ESTestEntity;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;

import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ElasticsearchTemplateTest1 {

    @Autowired
    private ESTestRepository esTestRepository;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations; // 注意这里使用 ElasticsearchOperations

    private static final Long TEST_ID = 1L;
    private static final String TEST_TITLE = "测试标题";
    private static final String TEST_CONTENT = "测试内容";
    private static final String TEST_EXCERPT = "测试摘要";
    private static final String UPDATED_TITLE = "更新后的标题";

//    @BeforeEach
//    void setUp() {
//        // 清除测试数据
//        esTestRepository.deleteAll();
//    }

    @Test
    @Order(1)
    void testSaveEntity() {
        // 创建测试实体
        ESTestEntity entity = createTestEntity();

        // 保存实体
        ESTestEntity savedEntity = elasticsearchOperations.save(entity);

        // 验证保存结果
        assertNotNull(savedEntity.getId(), "保存后ID不应为null");
        assertEquals(TEST_TITLE, savedEntity.getTitle(), "标题不匹配");
        assertEquals(TEST_CONTENT, savedEntity.getContent(), "内容不匹配");
        assertEquals(TEST_EXCERPT, savedEntity.getExcerpt(), "摘要不匹配");

        // 通过ID查询验证
        Optional<ESTestEntity> foundEntity = esTestRepository.findById(TEST_ID);
        System.out.println(foundEntity);
        assertTrue(foundEntity.isPresent(), "应该能找到保存的实体");
        assertEquals(TEST_TITLE, foundEntity.get().getTitle(), "查询到的标题不匹配");
    }

    @Test
    @Order(2)
    void testUpdateEntity() {
        // 先保存一个实体
        ESTestEntity entity = createTestEntity();
        elasticsearchOperations.save(entity);

        // 更新实体
        entity.setTitle(UPDATED_TITLE);
        ESTestEntity updatedEntity = elasticsearchOperations.save(entity);

        // 验证更新结果
        assertEquals(UPDATED_TITLE, updatedEntity.getTitle(), "更新后的标题不匹配");

        // 通过ID查询验证
        Optional<ESTestEntity> foundEntity = esTestRepository.findById(TEST_ID);
        System.out.println(foundEntity);
        assertTrue(foundEntity.isPresent(), "应该能找到更新后的实体");
        assertEquals(UPDATED_TITLE, foundEntity.get().getTitle(), "查询到的标题不匹配");
    }

    @Test
    @Order(3)
    void testFindEntityById() {
        // 保存一个实体
        ESTestEntity entity = createTestEntity();
        elasticsearchOperations.save(entity);

        // 通过ID查询
        Optional<ESTestEntity> foundEntity = esTestRepository.findById(TEST_ID);
        System.out.println(foundEntity);
        // 验证查询结果
        assertTrue(foundEntity.isPresent(), "找到实体");
        assertEquals(TEST_TITLE, foundEntity.get().getTitle(), "标题不匹配");
        assertEquals(TEST_CONTENT, foundEntity.get().getContent(), "内容不匹配");
    }

    @Test
    @Order(4)
    void testFindAllEntities() {
//        // 保存多个实体
//        for (int i = 1; i <= 3; i++) {
//            ESTestEntity entity = createTestEntity();
//            entity.setId((long) i);
//            entity.setTitle("标题" + i);
//            elasticsearchOperations.save(entity);
//        }

        // 查询所有实体 - 返回 Page 对象
        Page<ESTestEntity> entityPage = esTestRepository.findAll(PageRequest.of(0, 10));
        System.out.println(entityPage.getContent());
//        // 验证查询结果
//        assertEquals(3, entityPage.getTotalElements(), "实体数量不匹配");
//        assertEquals(3, entityPage.getContent().size(), "分页内容大小不匹配");
    }

    @Test
    @Order(5)
    void testDeleteEntity() {
        // 保存一个实体
        ESTestEntity entity = createTestEntity();
        elasticsearchOperations.save(entity);

        // 删除实体
        elasticsearchOperations.delete(entity);

        // 验证删除结果
        Optional<ESTestEntity> foundEntity = esTestRepository.findById(TEST_ID);
                System.out.println(foundEntity);
        assertFalse(foundEntity.isPresent(), "实体应该已被删除");
    }

    @Test
    @Order(6)
    void testDeleteEntityById() {
        // 保存一个实体
        ESTestEntity entity = createTestEntity();
        elasticsearchOperations.save(entity);

        // 通过ID删除实体
        esTestRepository.deleteById(TEST_ID);

        // 验证删除结果
        Optional<ESTestEntity> foundEntity = esTestRepository.findById(TEST_ID);
        System.out.println(foundEntity);
        assertFalse(foundEntity.isPresent(), "实体应该已被删除");
    }

    @Test
    @Order(7)
    void testSearchByTitle() {
        // 保存测试数据
        ESTestEntity entity1 = createTestEntity();
        entity1.setTitle("Spring Data ES");
        elasticsearchOperations.save(entity1);

        ESTestEntity entity2 = createTestEntity();
        entity2.setId(2L);
        entity2.setTitle("Elasticsearch Tutorial");
        elasticsearchOperations.save(entity2);

        // 使用旧版API构建查询
        Query searchQuery = new CriteriaQuery(
                new Criteria("title").contains("Elasticsearch")
        );

        // 执行搜索
        SearchHits<ESTestEntity> searchHits = elasticsearchOperations.search(
                searchQuery,
                ESTestEntity.class
        );

        // 验证搜索结果
        assertEquals(1, searchHits.getTotalHits(), "搜索结果数量不匹配");
        SearchHit<ESTestEntity> hit = searchHits.getSearchHits().get(0);
        System.out.println(hit);
        assertEquals("Elasticsearch Tutorial", hit.getContent().getTitle(), "搜索结果标题不匹配");
    }

    private ESTestEntity createTestEntity() {
        ESTestEntity entity = new ESTestEntity();
        entity.setId(TEST_ID);
        entity.setTitle(TEST_TITLE);
        entity.setContent(TEST_CONTENT);
        entity.setExcerpt(TEST_EXCERPT);
        return entity;
    }
}